import { OnInit, OnChanges, OnDestroy, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, TemplateRef, NgZone, ViewChild, ElementRef } from '@angular/core';
import { InputNumber, InputBoolean } from 'ng-zorro-antd';
import { Lbchart } from '@shared';
import { Subscription } from 'rxjs';
/**
 * 堆叠折线图
 */
@Component({
  selector: 'lb-stack-line',
  template: `
  <div #stackline></div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush, // 检测改为按需，即不自动刷新
})
export class LbStackLineComponent  implements OnInit, OnChanges, OnDestroy,Lbchart{
  private chart: any;
  private resize$: Subscription;
  @ViewChild('stackline', { static: true }) private node: ElementRef;
  @Input() padding: Array<number | string> | string = 'auto';
  @Input() @InputNumber() delay = 0;
  @Input() color:string[] = null;
  @Input() colorFiled='name';
  @Input() position: any

  // @Input() style: { [key: string]: string };
  // @Input() position: { x: string, y: string, z: string } = { x: 'adc', y: 'sold', z: 'type' }
  @Input() keyfield: Array<string>
  @Input() shape: string = 'line'

  @Input() data: any [] 

  @Input() width: number;
  @Input() height: number;

  @Input() @InputBoolean() legendshow = false
  @Input() legendposition 
  @Input() legendlayout
  @Input() @InputBoolean() tooltipshow = true;
  @Input() @InputBoolean() tooltipshowtitle = true
  @Input() @InputBoolean() areashow = true;
  @Input() @InputBoolean() pointshow = false;
  @Input() pointshape = 'circle';
  @Input() @InputNumber() pointsize = 5
  @Input() pointcolor = ''
  @Input() @InputBoolean() lineshow = true;
  @Input() lineshape = 'smooth'

  @Input() sortx = true
  @Input() sortz
  @Input() sortrule = 'ASC'

  line: any
  point: any
  area: any

  constructor(private ngZone: NgZone) { }

  install() {
    this.render()
  }

  commonStyleHandle(chart, data) {
    const dv = new DataSet.View().source(data);
    // if(this.sortx && !this.sortz) {
    //   dv.transform({
    //     type: 'sort-by',
    //     fields: [ this.position.x ], // 根据指定的字段集进行排序，与lodash的sortBy行为一致
    //     order: this.sortrule,        // 默认为 ASC，DESC 则为逆序
    //   })
    // } else if(!this.sortx && this.sortz){
    //   dv.transform({
    //     type: 'sort-by',
    //     fields: [ this.position.z ], // 根据指定的字段集进行排序，与lodash的sortBy行为一致
    //     order: this.sortrule,   // 默认为 ASC，DESC 则为逆序
    //   })
    // } else if(this.sortx && this.sortz) {
    //   dv.transform({
    //     type: 'sort-by',
    //     fields: [ this.position.x, this.position.z ], // 根据指定的字段集进行排序，与lodash的sortBy行为一致
    //     order: this.sortrule,   // 默认为 ASC，DESC 则为逆序
    //   })
    // }    

    chart.source(dv.rows);

    // legend
    chart.legend(this.position.x, false)
    if (this.legendshow) {
      chart.legend(this.position.z, {
        position: this.legendposition,
        layout: this.legendlayout,
      });
    } else {
      chart.legend(false);
    }

    // tooltip
    if(this.tooltipshow) {
      chart.tooltip({
        showTitle: this.tooltipshowtitle,
        crosshairs: {
          type: 'line',
        },
      });
    } else {
      chart.tooltip(false)
    }

    if (this.lineshow === true) {
      if (this.line === undefined) {
        this.line = chart
          .lineStack()
          .position(`${this.position.x}*${this.position.y}`)
          .color(this.position.z)
          .shape(this.position.z, z => this.lineshape);
      } else {
        this.line.show();
      }
    } else {
      if (this.line) this.line.hide();
    }
    if (this.line) this.line.shape(this.lineshape);

    // area
    if (this.areashow === true) {
      if (this.area === undefined) {
        this.area = chart
          .areaStack()
          .position(`${this.position.x}*${this.position.y}`)
          .color(this.position.z)
          .shape(this.lineshape)
      } else {
        this.area.show();
      }
    } else {
      if (this.area) this.area.hide();
    }
    if (this.area) this.area.shape(this.lineshape);

    // point
    if (this.pointshow === true) {
      if (this.point === undefined) {
        this.point = chart
          .pointStack()
          .position(`${this.position.x}*${this.position.y}`)
          .size(this.position.z, z => {
            return this.pointsize
          })
          .shape(this.position.z ,z => {
            return this.pointshape
          })
          .color(this.position.z)
          .style({
            stroke: '#fff',
            lineWidth: 1,
          })
      } else {
        this.point.show();
      }
    } else {
      if (this.point) this.point.hide();
    }



    return dv.rows;
  }

  render() {
    const { node, padding } = this;
    const container = node.nativeElement as HTMLElement;

    const chart = (this.chart = new G2.Chart({
      container,
      forceFit: true,  // 图表的宽度自适应开关
      height: this.getHeight(),
      padding,
    }));

   
    // chart
    //   .lineStack()
    //   .position(`${this.position.x}*${this.position.y}`)
    //   .color(`${this.position.z}`)
    //   .shape(this.shape)
      
    // if(this.area == true)
    //   chart
    //     .areaStack()
    //     .position(`${this.position.x}*${this.position.y}`)
    //     .color(`${this.position.z}`)
        
    // if(this.point == true)
    //   chart
    //     .pointStack().position(`${this.position.x}*${this.position.y}`)
    //     .color(`${this.position.z}`)
    //     .size(4)
    //     .shape('circle')
    //     .style({
    //       stroke: '#fff',
    //       lineWidth: 1
    //     });

    // // Step 4: 渲染图表
    this.commonStyleHandle(chart, this.data)
    chart.render();

    // this.attachChart();
  }

   attachChart() {
    const { chart, padding, data, color } = this;
    if (!chart || !data || data.length <= 0) return;
    const height = this.getHeight();
    if (chart.get('height') !== height) {
      chart.changeHeight(height);
    }

    const dvrows = this.commonStyleHandle(chart, this.data)
     // color
    //  chart.get('geoms')[0].color(this.colorFiled,this.color);
     chart.set('padding', padding);
     chart.changeData(dvrows);
  }

  destroy(){
    if (this.resize$) {
      this.resize$.unsubscribe();
    }
    if (this.chart) {
      this.ngZone.runOutsideAngular(() => this.chart.destroy());
    }
  }

  /**
   * 报表高度
   * 存在报表头，则需要减掉报表头的高度
   */
   getHeight() {
     return this.height
    // return this.title ? (this.height - TITLE_HEIGHT) : this.height;
  }


  ngOnInit(): void {
    if(this.position&&this.data.length>0){
      this.ngZone.runOutsideAngular(() => setTimeout(() => this.install(), this.delay));
    }
   
  }  
  
  ngOnChanges(changes: import("@angular/core").SimpleChanges): void {
    this.ngZone.runOutsideAngular(() => this.attachChart());
  }
  ngOnDestroy(): void {
    this.destroy();
  }
} 